﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

namespace Paxman.Objects
{
    /// <summary>
    /// Classe base dos objetos que possuem movimento
    /// e são desenhados na tela
    /// </summary>
    public abstract class Sprite
    {
        /// <summary>Posição do sprite</summary>
        public Vector2 position;

        /// <summary>Textura</summary>
        public Texture2D texture;

        /// <summary>Animação atual, ou null se não estiver animando</summary>
        protected Animation currentAnimation;

        /// <summary>Largura</summary>
        public int Width
        {
            get
            {
                if (currentAnimation != null)
                    return currentAnimation.frameWidth;
                else
                    return texture.Width;
            }
        }

        /// <summary>Altura</summary>
        public int Height
        {
            get
            {
                if (currentAnimation != null)
                    return currentAnimation.frameHeight;
                else
                    return texture.Height;
            }
        }
        
        /// <summary>Velocidade</summary>
        protected int vel;

        /// <summary>Quadrado de colisão</summary>
        public Rectangle CollisionRect
        {
            get { return new Rectangle((int)position.X, (int)position.Y, Width, Height); }
        }

        /// <summary>Centro do sprite</summary>
        public Vector2 Center
        {
            get { return new Vector2(CollisionRect.Center.X, CollisionRect.Center.Y); }
            set
            {
                Vector2 p = (Vector2)value;
                position.X = p.X - (Width / 2);
                position.Y = p.Y - (Height / 2);
            }
        }

        /// <summary>Deslocamento adicional em x no momento do Draw</summary>
        protected int xOffset = 0;

        /// <summary>Deslocamento adicional em y no momento do Draw</summary>
        protected int yOffset = 0;

        /// <summary>Seta um deslocamento no momento do Draw</summary>
        public void SetOffset(int x, int y)
        {
            xOffset = x;
            yOffset = y;
        }

        /// <summary>Carrega a textura básica do sprite</summary>
        /// <param name="content">Content para carregar a imagem</param>
        /// <param name="imageFile">Nome da imagem (sem extensão)</param>
        public void LoadTexture(ContentManager content, string imageFile)
        {
            texture = content.Load<Texture2D>(imageFile);
        }

        /// <summary>Desenha o sprite</summary>
        public virtual void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            // se houver alguma animação, desenha o frame atual
            // senão desenha a textura completa
            if (currentAnimation != null)
            {
                // retangulo de origem da imagem e retangulo de destino
                Rectangle rectSource = new Rectangle(currentAnimation.currentFrame * currentAnimation.frameWidth, currentAnimation.mapY,
                    currentAnimation.frameWidth, currentAnimation.frameHeight);
                Rectangle rectDest = new Rectangle((int)position.X + xOffset, (int)position.Y + yOffset, currentAnimation.frameWidth, currentAnimation.frameHeight);

                if (currentAnimation.IsPlaying())
                {
                    // passa para o proximo frame enquanto estiver em play
                    double totalTimeAnim = gameTime.TotalGameTime.TotalSeconds - currentAnimation.startTime;
                    int frame = (int)(totalTimeAnim * currentAnimation.frameRate) % currentAnimation.frameCount;
                    if (frame == 0)
                        currentAnimation.currentFrame = 0;
                    else if (frame > currentAnimation.currentFrame)
                        currentAnimation.currentFrame++;

                    // para a animação se foi endicado para parar no fim
                    if (currentAnimation.stopEnd && currentAnimation.currentFrame == (currentAnimation.frameCount - 1))
                        currentAnimation.Pause();
                }

                spriteBatch.Draw(texture, rectDest, rectSource, new Color(1.0f * 1, 1.0f * 1, 1.0f * 1, 1), 0, Vector2.Zero, SpriteEffects.None, 1);
            }
            else
                spriteBatch.Draw(texture, new Vector2(position.X + xOffset, position.Y + yOffset), Color.White);
        }
    }
}
